package cc.rengu.igas.share.core.service.asyncall;

import cc.rengu.igas.acct.facade.bean.MchtAdjustDetail;
import cc.rengu.igas.acct.facade.response.VirtAcctMultiMchntAdjustResponse;
import cc.rengu.igas.acct.facade.result.Result;
import cc.rengu.oltp.service.base.DubboAsynBaseService;
import cc.rengu.oltp.service.common.constant.TreeNodeConstant;
import cc.rengu.oltp.service.common.dao.PayOrderInfoMapper;
import cc.rengu.oltp.service.common.dao.impl.MchntOrderInfoMapperImpl;
import cc.rengu.oltp.service.common.dao.impl.PayOrderInfoMapperImpl;
import cc.rengu.oltp.service.common.entity.MchntOrderInfo;
import cc.rengu.oltp.service.common.entity.PayOrderInfo;
import cc.rengu.oltp.service.common.enums.BizStatusEnum;
import cc.rengu.oltp.service.common.enums.ChannelEnum;
import cc.rengu.oltp.service.common.enums.OltpRpcdEnum;
import cc.rengu.oltp.service.common.enums.TransStatusEnum;
import cc.rengu.oltp.service.model.BizException;
import cc.rengu.oltp.service.realize.OrderService;
import cc.rengu.oltp.service.realize.impl.OrderServiceImpl;
import cc.rengu.oltp.utility.annotation.BIZ_PROCESS;
import cc.rengu.oltp.utility.util.DateUtil;
import cc.rengu.oltp.utility.util.XmlTreeUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;

import java.util.List;
import java.util.stream.Collectors;

/**
 * 虚拟账户记账异步处理
 */
public class AsynVirtAcctMultiMchntAdjustService extends DubboAsynBaseService {

    @BIZ_PROCESS
    public void virtAcctMultiMchntAdjust() throws Exception {

        XmlTreeUtil xmlTreeUtil = new XmlTreeUtil();
        String sysNo;
        String instId;
        /*判断记账结果，更新支付订单状态*/
        if (!xmlTreeUtil.isExist(TreeNodeConstant.DUBBO_RESPONSE)) {
            rglog.error("dubbo调用虚拟账户记账失败");
            return;
        }
        rglog.debug("dubbo调用正常返回");
        Result<JSONObject> responseResult = (Result<JSONObject>) xmlTreeUtil.getXmlTreeObjectValue(TreeNodeConstant.DUBBO_RESPONSE, Result.class);
        VirtAcctMultiMchntAdjustResponse response = JSON.toJavaObject(responseResult.getResult(), VirtAcctMultiMchntAdjustResponse.class);
        /*避免支付成功发起记账跟查询交易发起记账系统流水号不一致的问题,取调用虚拟账户记账的traceNo*/
        if (response.getHeader() != null && response.getHeader().getTraceNo() != null) {
            sysNo = response.getHeader().getTraceNo().substring(0, 32);
            instId = xmlTreeUtil.getXmlTreeStringValue(TreeNodeConstant.INST_ID);
        } else {
            rglog.error("dubbo调用虚拟账户记账失败");
            return;
        }

        /*获取支付订单列表*/
        PayOrderInfoMapper payOrderInfoMapper = new PayOrderInfoMapperImpl();
        List<PayOrderInfo> payOrderInfoList = payOrderInfoMapper.selectPayOrderInfoBySysSeqNum(instId, sysNo);
        if (payOrderInfoList == null || payOrderInfoList.size() == 0) {
            rglog.error("根据机构号<{}>、系统流水号<{}>获取支付订单列表失败", instId, sysNo);
            return;
        }
        List<PayOrderInfo> payOrderInfoListAcct = payOrderInfoList.stream().filter(item -> item.getMsgDstId().equals(ChannelEnum.ACCT.getChannelType())).collect(Collectors.toList());
        if (payOrderInfoListAcct.size() != 1) {
            rglog.error("查询虚拟支付订单流水记录异常");
            throw new BizException(OltpRpcdEnum.OLTP_PROCESS_ERROR.getRespCode(), OltpRpcdEnum.OLTP_PROCESS_ERROR.getRespDesc());
        }
        PayOrderInfo payOrderInfo = payOrderInfoListAcct.get(0);
        OrderService orderService = new OrderServiceImpl();

        /*判断记账结果，更新支付订单状态*/
        if (!responseResult.isSuccess() || !xmlTreeUtil.isExist(TreeNodeConstant.DUBBO_RESPONSE)) {
            rglog.warn("dubbo调用虚拟账户记账失败");
            payOrderInfo.setTransStatus(TransStatusEnum.SYSTEM_REJECT.getStatus());
            payOrderInfo.setBizStatus(BizStatusEnum.FAILED.getStatus());
            payOrderInfo.setUpdateTime(DateUtil.getCurrentDateTime("yyyy-MM-dd HH:mm:ss.SSS"));
            if (!orderService.updateOrderInfo(null, null, payOrderInfo)) {
                rglog.warn("更新订单表状态失败");
            }
            return;
        }

        //虚拟账户记账失败
        if (!OltpRpcdEnum.TRANS_SUCCESS.getRespCode().equals(response.getRespCode()) || !"00".equals(response.getTransStatus())) {
            rglog.warn("业务处理失败respCode<{}>,respDesc<{}>", response.getRespCode(), response.getRespDesc());
            if (BizStatusEnum.PROCESSING.getStatus().equals(payOrderInfo.getBizStatus())) {
                /*更新支付订单表失败*/
                payOrderInfo.setTransStatus(TransStatusEnum.SYSTEM_REJECT.getStatus());
                payOrderInfo.setBizStatus(BizStatusEnum.FAILED.getStatus());
                payOrderInfo.setRespCode(response.getRespCode());
                payOrderInfo.setRespDesc(response.getRespDesc());
                payOrderInfo.setUpdateTime(DateUtil.getCurrentDateTime("yyyy-MM-dd HH:mm:ss.SSS"));
                if (!orderService.updateOrderInfo(null, null, payOrderInfo)) {
                    rglog.error("更新订单表状态失败");
                }
                return;
            } else {
                rglog.info("订单[{}]业务状态[{}]非业务处理中.不更新", payOrderInfo.getSysSeqNum(), payOrderInfo.getBizStatus());
                return;
            }
        }
        /*更新支付订单表成功*/
        payOrderInfo.setTransStatus(TransStatusEnum.TRANS_SUCC.getStatus());
        payOrderInfo.setBizStatus(BizStatusEnum.FINISH.getStatus());
        payOrderInfo.setSettleDate(response.getAcctDate());
        payOrderInfo.setRespCode(response.getRespCode());
        payOrderInfo.setRespDesc(response.getRespDesc());
        payOrderInfo.setUpdateTime(DateUtil.getCurrentDateTime("yyyy-MM-dd HH:mm:ss.SSS"));
        if (!orderService.updateOrderInfo(null, null, payOrderInfo)) {
            rglog.warn("更新订单表状态失败");
        }
        rglog.warn("更新订单表状态成功");
        //更新商户订单表中的虚拟账户余额
        MchntOrderInfoMapperImpl mchntOrderInfoMapper = new MchntOrderInfoMapperImpl();
        List<MchntOrderInfo> mchntOrderInfos = mchntOrderInfoMapper.selectMchntOrderInfoBySysSeqNum(instId, sysNo);
        if (null == mchntOrderInfos || mchntOrderInfos.isEmpty()) {
            rglog.warn("商户订单不存在，instId:<{}>,sysSeqNo:<{}>", instId, sysNo);
            return;
        }
        List<MchtAdjustDetail> mchtAdjustDetailList = response.getMchtAdjustDetailList();
        for (MchtAdjustDetail mchtAdjustDetail : mchtAdjustDetailList) {
            rglog.warn("过滤商户");
            List<MchntOrderInfo> matchMchntOrders = mchntOrderInfos.stream().filter(item -> item.getMchntNo().equals(mchtAdjustDetail.getUserId())).collect(Collectors.toList());
            if (matchMchntOrders.isEmpty()) {
                rglog.warn("过滤平台商户");
                matchMchntOrders = mchntOrderInfos.stream().filter(item -> item.getChainMchntNo().equals(mchtAdjustDetail.getUserId())).collect(Collectors.toList());
                if (matchMchntOrders.isEmpty()) {
                    rglog.warn("当前返回列表中不存在该商户订单，mchntNo:<{}>", mchtAdjustDetail.getUserId());
                    throw new BizException(OltpRpcdEnum.OLTP_PROCESS_ERROR.getRespCode(), OltpRpcdEnum.OLTP_PROCESS_ERROR.getRespDesc());
                }
            }
            rglog.warn("设置虚拟账户余额");
            matchMchntOrders.stream().forEach(item -> item.setVirtualAcctBalance(mchtAdjustDetail.getAfterBalance()));
        }
        rglog.warn("更新订单表状态成功");
        if (!orderService.updateOrderInfo(null, mchntOrderInfos, null)) {
            rglog.warn("更新商户订单表商户虚拟账户余额失败");
        }
        xmlTreeUtil.setXmlTreeStringValue(TreeNodeConstant.SYS_SEQ_NUM, sysNo);
        rglog.debug("开始异步调用消息推送交易......");
        /*记账成功后，调用微信消息推送*/
        int iReturnCode = asynnotify.transactionNotice("MchntTransNoticeService", 1, 0, 0);
        if (0 != iReturnCode) {
            rglog.error("提交交易结果异步通知给商户失败!");
        }
    }
}
